package com.fc.test.controller;

import com.alibaba.fastjson.JSON;
import com.fc.test.common.domain.AjaxResult;
import com.fc.test.model.auto.EntUser;
import com.fc.test.model.auto.StuInfo;
import com.fc.test.shiro.service.LoginType;
import com.fc.test.shiro.service.UserToken;
import com.fc.test.shiro.util.ShiroUtils;
import com.fc.test.util.StringUtils;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.security.SecurityUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.Security;


@Slf4j
@Controller
@RequestMapping("/auth")
public class AuthController {

    @ApiOperation(value="退出登陆",notes="退出登陆")
    @GetMapping("/Loginout")
    public AjaxResult LoginOut(HttpServletRequest request, HttpServletResponse response){
        //在这里执行退出系统前需要清空的数据
        Subject subject = SecurityUtils.getSubject();
        //注销
        subject.logout();
        return AjaxResult.success();
    }

    @GetMapping("/student/authenticate")
    public  AjaxResult authStu(){
        Subject subject=SecurityUtils.getSubject();

        if(subject==null){
            return AjaxResult.error(500,"尚未登陆");
        }
        if(subject.hasRole("stu")){
            StuInfo stuInfo=(StuInfo)subject.getPrincipal();
            return AjaxResult.success(String.valueOf(stuInfo.getSid()));
        }else {
            return AjaxResult.error("校验失败");
        }

    }

    @GetMapping("/enterprise/authenticate")
    public  AjaxResult authEnt(){
        Subject subject=SecurityUtils.getSubject();
        if(subject==null){
            return AjaxResult.error(500,"尚未登陆");
        }
        if(subject.hasRole("ent")){
            EntUser entUser=(EntUser)subject.getPrincipal();
            return AjaxResult.success(String.valueOf(entUser.getEid()));
        }else {
            return AjaxResult.error("校验失败");
        }

    }
    @PostMapping("/student/login")
    @ResponseBody
    public AjaxResult stuLogin(@RequestBody  StuInfo stuInfo){

        String userName = stuInfo.getAccount();
        Subject currentUser = SecurityUtils.getSubject();
        //是否验证通过
        if(!currentUser.isAuthenticated()) {
            UserToken token =new UserToken(userName,stuInfo.getPassword(), LoginType.STUDENT.toString());
            try {

                token.setRememberMe(true);

                //存入用户
                currentUser.login(token);

                //跳转到 get请求的登陆方法
                //view.setViewName("redirect:/"+prefix+"/index");
                if(StringUtils.isNotNull(ShiroUtils.getEnterpriseUser())){
                    return  AjaxResult.success(ShiroUtils.getStudentUser().getSid()+"");
                }else {
                    return AjaxResult.error("登录失败");
                }


            }catch (UnknownAccountException uae) {
                log.info("对用户[" + userName + "]进行登录验证..验证未通过,未知账户");
                return  AjaxResult.error(500,"未知账户");
            } catch (IncorrectCredentialsException ice) {
                log.info("对用户[" + userName + "]进行登录验证..验证未通过,错误的凭证");
                return AjaxResult.error(500, "用户名或密码不正确");
            } catch (LockedAccountException lae) {
                log.info("对用户[" + userName + "]进行登录验证..验证未通过,账户已锁定");
                return AjaxResult.error(500,"账户已锁定");
            } catch (ExcessiveAttemptsException eae) {
                log.info("对用户[" + userName + "]进行登录验证..验证未通过,错误次数过多");
                return AjaxResult.error(500,"用户名或密码错误次数过多");
            } catch (AuthenticationException ae) {
                //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
                log.info("对用户[" + userName + "]进行登录验证..验证未通过,堆栈轨迹如下");
                ae.printStackTrace();
                return AjaxResult.error(500,"用户名或密码不正确");
            }
        }else {
            if(StringUtils.isNotNull(ShiroUtils.getStudentUser())) {
                //跳转到 get请求的登陆方法
                //view.setViewName("redirect:/"+prefix+"/index");

                return  AjaxResult.success(""+ShiroUtils.getStudentUser().getSid());
            }else {
                return  AjaxResult.error(500,"未知账户");
            }
        }

    }
    @PostMapping("/enterprise/login")
    @ResponseBody
    public AjaxResult entLogin(@RequestBody  EntUser entUser){
        String userName = entUser.getName();
        Subject currentUser = SecurityUtils.getSubject();
        //是否验证通过
        if(!currentUser.isAuthenticated()) {
            UserToken token =new UserToken(userName,entUser.getUpassword(), LoginType.Enterprise.toString());
            try {

                token.setRememberMe(true);

                //存入用户
                currentUser.login(token);

                //跳转到 get请求的登陆方法
                //view.setViewName("redirect:/"+prefix+"/index");
                if(StringUtils.isNotNull(ShiroUtils.getEnterpriseUser())){
                    return  AjaxResult.success(ShiroUtils.getEnterpriseUser().getEid()+"");
                }else {
                    return AjaxResult.error("登录失败");
                }


            }catch (UnknownAccountException uae) {
                log.info("对用户[" + userName + "]进行登录验证..验证未通过,未知账户");
                return  AjaxResult.error(500,"未知账户");
            } catch (IncorrectCredentialsException ice) {
                log.info("对用户[" + userName + "]进行登录验证..验证未通过,错误的凭证");
                return AjaxResult.error(500, "用户名或密码不正确");
            } catch (LockedAccountException lae) {
                log.info("对用户[" + userName + "]进行登录验证..验证未通过,账户已锁定");
                return AjaxResult.error(500,"账户已锁定");
            } catch (ExcessiveAttemptsException eae) {
                log.info("对用户[" + userName + "]进行登录验证..验证未通过,错误次数过多");
                return AjaxResult.error(500,"用户名或密码错误次数过多");
            } catch (AuthenticationException ae) {
                //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
                log.info("对用户[" + userName + "]进行登录验证..验证未通过,堆栈轨迹如下");
                ae.printStackTrace();
                return AjaxResult.error(500,"用户名或密码不正确");
            }
        }
         else {
            if(StringUtils.isNotNull(ShiroUtils.getEnterpriseUser())) {
                //跳转到 get请求的登陆方法
                //view.setViewName("redirect:/"+prefix+"/index");
                return  AjaxResult.success(ShiroUtils.getEnterpriseUser().getEid()+"");
            }else {
                return  AjaxResult.error(500,"未知账户");
            }
        }

    }

    private AjaxResult getAjaxResult(String userName, Subject currentUser, UserToken token) {
        try {

            token.setRememberMe(true);

            //存入用户
            currentUser.login(token);

                //跳转到 get请求的登陆方法
                //view.setViewName("redirect:/"+prefix+"/index");
            if(StringUtils.isNotNull(SecurityUtils.getSubject().getPrincipal())){
                return  AjaxResult.success();
            }else {
                return AjaxResult.error("登录失败");
            }


        }catch (UnknownAccountException uae) {
            log.info("对用户[" + userName + "]进行登录验证..验证未通过,未知账户");
            return  AjaxResult.error(500,"未知账户");
        } catch (IncorrectCredentialsException ice) {
            log.info("对用户[" + userName + "]进行登录验证..验证未通过,错误的凭证");
            return AjaxResult.error(500, "用户名或密码不正确");
        } catch (LockedAccountException lae) {
            log.info("对用户[" + userName + "]进行登录验证..验证未通过,账户已锁定");
            return AjaxResult.error(500,"账户已锁定");
        } catch (ExcessiveAttemptsException eae) {
            log.info("对用户[" + userName + "]进行登录验证..验证未通过,错误次数过多");
            return AjaxResult.error(500,"用户名或密码错误次数过多");
        } catch (AuthenticationException ae) {
            //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
            log.info("对用户[" + userName + "]进行登录验证..验证未通过,堆栈轨迹如下");
            ae.printStackTrace();
            return AjaxResult.error(500,"用户名或密码不正确");
        }
    }
}
